var canvas;
var gl;

var Program;

var NumPoints;
var ColorArray;

var MouseDown = false;
var LastMouseX;
var LastMouseY;
var Left, Middle, Right;
var Perspective;
var SaveScale = 1.;

var MvMatrix = mat4.create( );
var PMatrix  = mat4.create( );
var MvLoc;
var PLoc;
var ModelMatrix = mat4.create( );

function InitGraphics( )
{
	canvas = document.getElementById( "gl-canvas" );
	
	gl = WebGLUtils.setupWebGL( canvas );
	if( !gl )
	{
		alert( "WebGL isn't available" );
	}

	canvas.onmousedown   = HandleMouseDown;
	document.onmouseup   = HandleMouseUp;
	document.onmousemove = HandleMouseMove;

	// set globals:

	Perspective = true;
	mat4.identity( ModelMatrix );

	//  load shaders:

	Program = InitShaders( gl, "vertex-shader", "fragment-shader" );
	gl.useProgram( Program );

	MvLoc = gl.getUniformLocation( Program, "uModelViewMatrix" );
	CheckError( "mvLoc " );
	PLoc  = gl.getUniformLocation( Program, "uProjectionMatrix" );
	CheckError( "PLoc " );

	// setup ui:

	var b1 = document.getElementById( "PerspButton" );
	b1.addEventListener( "click", function( ) { Perspective =  true; Display( ); }, false );

	b2 = document.getElementById( "OrthoButton" )
	b2.addEventListener( "click", function( ) { Perspective = false; Display( ); }, false );

	// initialize the data:

	InitData( );

	InitCL();
	clCompute();
	// put the data in opengl buffers:

	colorBufferId = gl.createBuffer( );
	gl.bindBuffer( gl.ARRAY_BUFFER, colorBufferId );
	gl.bufferData( gl.ARRAY_BUFFER, ColorArray, gl.STATIC_DRAW );
	var cLoc = gl.getAttribLocation( Program, "aColor" );
	gl.vertexAttribPointer( cLoc, 3, gl.FLOAT, false, 0, 0 );
	gl.enableVertexAttribArray( cLoc );
	
	vertexBufferId = gl.createBuffer( );
	gl.bindBuffer( gl.ARRAY_BUFFER, vertexBufferId );
	gl.bufferData( gl.ARRAY_BUFFER, XYZArray, gl.DYNAMIC_DRAW );
	var vLoc = gl.getAttribLocation( Program, "aVertex" );
	gl.vertexAttribPointer( vLoc, 4, gl.FLOAT, false, 0, 0 );
	gl.enableVertexAttribArray( vLoc );

	startTime = performance.now();
	
	// get everything running:
	Animate( );
}


function Animate( )
{
	clCompute();

	time0 = performance.now(); //timecheck 3
	gl.bufferSubData( gl.ARRAY_BUFFER, 0, XYZArray );
	var vLoc = gl.getAttribLocation( Program, "aVertex" );
	gl.vertexAttribPointer( vLoc, 4, gl.FLOAT, false, 0, 0 );
	gl.enableVertexAttribArray( vLoc );
	
	time1 = performance.now(); //timecheck 3
	elapsedTimesRaw[timeIDX] = time1-time0;
	if (timeIDX >= NUMMEASURES) {
		displayResults();
		return true;
	}
	timeIDX++;
		
	requestAnimFrame( Animate );
	Display( );
}


function Display( )
{
	time0 = performance.now(); //timecheck 4
	gl.clearColor( 0.0, 0.0, 0.0, 1.0 );
	gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
	gl.viewport( 0, 0, canvas.width, canvas.height );

	// projection matrix:

	if( Perspective )
	{
		PMatrix = mat4.perspective( 60., 1., 0.1, 100.0 );
	}
	else
	{
		PMatrix = mat4.ortho( -2., 2.,  -2., 2.,  0.1, 100. );
	}

	// read the scaling slider:

	var s = $( "#slider" ).slider( "value" );
	if( s != SaveScale )
	{
		var newScaleMatrix = mat4.create( );
		mat4.identity( newScaleMatrix );
		var s2 = s / SaveScale;
		mat4.scale( newScaleMatrix, [ s2, s2, s2 ] );
		mat4.multiply( newScaleMatrix, ModelMatrix, ModelMatrix );
		SaveScale = s;
	}

	// modelview matrix:

	gl.useProgram( Program );
	mat4.identity( MvMatrix );
	mat4.translate( MvMatrix, [0, 0, -4] );		// viewing
	mat4.multiply( MvMatrix, ModelMatrix );		// modeling
	gl.uniformMatrix4fv( MvLoc, false, MvMatrix );
	gl.uniformMatrix4fv( PLoc,  false, PMatrix );

	// do the drawing:
	gl.drawArrays( gl.POINTS, 0, NUMPARTICLES );
	
	gl.flush();
	gl.finish();
	
	time1 = performance.now(); //timecheck 4
	elapsedTimesRaw[timeIDX] = time1-time0;
	if (timeIDX >= NUMMEASURES) {
		displayResults();
		return true;
	}
	timeIDX++;
}

function CheckError( msg )
{
    var error = gl.getError( );
    if(  error != 0 )
    {
        var errMsg = "OpenGL error: " + error.toString(16);

        if ( msg )
	{
		errMsg = msg + "\n" + errMsg;
	}
        alert( errMsg );
    }
}